#include <stdio.h>
#include <stdlib.h>

#include "constantes.h"
#include "consola.h"
#include "comandos.h"
#include "TDiccionario.h"
#include "TTokenizer.h"
#include "TBuscador.h"

/* Comparador para mantener orden de insercion */
int comparadorOrderInsercion(void* elem1, void* elem2){
    return MAYOR;
}

/* Muestra Diccionario */
void mostrarDiccionario(TDiccionario* diccionario){
    /* Auxiliar para obtener valores a mostrar */
    char auxiliar[MAX_DATO];
    /* Obtiene y muestra por pantalla: numero de tweet, usuario, fecha */
    TDiccionario_obtener(diccionario, CLAVE_NUMERO_TWEET, auxiliar);
    printf("** Tweet numero %s **\n", auxiliar);
    TDiccionario_obtener(diccionario, CLAVE_FECHA_TWEET, auxiliar);
    printf("Fecha %s\n", auxiliar);
    TDiccionario_obtener(diccionario, CLAVE_USUARIO_TWEET, auxiliar);
    printf("Usuario %s\n", auxiliar);
    printf("****\n\n");
}

/* Muestra lista de resultados de las busquedas */
void mostrarResultados(TListaSimpleOrdenada* listaResultados){
    /* Diccionario auxuliar para procesar la lista */
    TDiccionario* pDic;
    TDiccionario diccionario;
    TDiccionario_Crear(&diccionario);
    /* Si la lista de diccionarios no esta vacia la procesa */
    if ( !lso_Vacia(*listaResultados) ){
        /* Mueve el corriente al primero */
        int resultadoMovimiento = lso_MoverCorriente(listaResultados, LS_PRIMERO);
        printf("*****Resultados de la busqueda****\n\n");
        /* Mientras se haya realizado el movimiento con exito sigue procesando */
        while(resultadoMovimiento==0){
            /* Obtiene el diccionario actual */
            lso_ElemCorriente(*listaResultados, &pDic);

            memcpy(&diccionario,pDic,sizeof(TDiccionario));


            /* Mustra el diccionario */
            mostrarDiccionario(&diccionario);
            /* Mueve el corriente al siguiente */
            resultadoMovimiento = lso_MoverCorriente(listaResultados, LS_SIGUIENTE);
        }
        printf("***** FIN Resultados de la busqueda****\n\n");
    }else{
        printf("No hubo resultados para la busqueda\n");
    }
}

/* Funcion principal, bucle de ingreso de comandos del usuario */
int main(int argc, char* argv[]){
    int idComandoLeido;
    int cantidadArgumentos;
    char lineaLeida[MAX_LONGITUD_LINEA];
    char arrayAgumentos[MAX_CANTIDAD_ARGUMENTOS][MAX_DATO];
    /* Tokenizer que se va a usar en el buscador */
    TTokenizer tokenizer;
    /* Buscador que se usa para los pedidos del usuario */
    TBuscador buscador;
    /* Lista que contendra los tweets resultantes de la busqueda */
    TListaSimpleOrdenada listaResultados;
    /* Crea el tokenizer */
    TTokenizer_crear(&tokenizer);
    /* Crea el buscador usando el tokenizer anteiror */
    TBuscador_crear(&buscador, &tokenizer);
    /* Crea la lista que contendra los diccionarios que representan los tweets
       encontrador */
    lso_Crear(&listaResultados, sizeof(TDiccionario*), &comparadorOrderInsercion);/**se crea afuera del while pero se destruye adentro, podria ocasinar un error**/
    /* Mientras el comendo obtenido por teclado no sea salir
       lo ejecuta */
    idComandoLeido = ID_COMANDO_INVALIDO;
    while (idComandoLeido!=ID_COMANDO_SALIR){
        /* Determina que comando ejecutar y obtiene sus argumentos */
        idComandoLeido = obtenerComandoDelUsuario(stdin, &cantidadArgumentos, arrayAgumentos, lineaLeida);
        /* Ejecuta el comando */
        if (idComandoLeido==ID_COMANDO_INVALIDO){
            printf("ERROR: el comando ingresado es invalido\n");
        }else if (idComandoLeido==CODIGO_ERROR_ARGUMENTOS_INVALIDOS){
            printf("ERROR: argumentos invalidos para el comando\n");
        }else{
            ejecutarComando(idComandoLeido, arrayAgumentos, &buscador, &listaResultados);
        }
        /* Si el tipo de comando necesita mostrar resultados los muestra */
        if (idComandoLeido==ID_COMANDO_AND || idComandoLeido==ID_COMANDO_OR){
            /* Muestra los resultados */
            mostrarResultados(&listaResultados);
            /* Vacia la lista de resultados */
            lso_Vaciar(&listaResultados);
        }
    }
    /* Se destruye el Tokenizer */
    TTokenizer_destruir(&tokenizer);
    /* Se destruye el Buscador */
    TBuscador_destruir(&buscador);
    /* Devuelve codigo de ejecucion correcta */
    return CODIGO_OK;
}
